package base.model;

import base.encoder.IEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 消息编码类
 * Created by wuhui on 2016/8/4.
 */
@Slf4j
public class NettyMessageEncoder extends MessageToMessageEncoder<NettyMessage> {
    //对消息进行编码，已接口形式提供，
    IEncoder iEncoder = null;
    public  NettyMessageEncoder(){
        iEncoder =  null;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        log.error(cause.getMessage(),cause);
    }

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, NettyMessage nettyMessage, List<Object> list) throws Exception {
        if (nettyMessage==null|| nettyMessage.getHeader()==null){
            throw new Exception("The encode message is null");
        }
        log.info(nettyMessage.toString());
        ByteBuf sendBuf = Unpooled.buffer();
        sendBuf.writeInt(nettyMessage.getHeader().getCrcCode());//前4个字节为魔数
        sendBuf.writeInt(nettyMessage.getHeader().getLength());//长度
        sendBuf.writeLong(nettyMessage.getHeader().getSessionId());//seeionid
        sendBuf.writeByte(nettyMessage.getHeader().getType());//消息类型
        sendBuf.writeByte(nettyMessage.getHeader().getPriority());//消息优先级
        sendBuf.writeInt(nettyMessage.getHeader().getAttachment().size());//附件长度
        String key = null;
        byte[] keyArray = null;
        Object value = null;
        //自定义附件输出
        for (Map.Entry<String,Object> param :nettyMessage.getHeader().getAttachment().entrySet()){
            key = param.getKey();
            keyArray = key.getBytes("UTF-8");
            sendBuf.writeInt(keyArray.length);
            sendBuf.writeBytes(keyArray);
            value = param.getValue();
            iEncoder.encode(value,sendBuf);
        }
        //垃圾回收
        key = null;
        keyArray = null;
        value  = null;
//        if(nettyMessage.getBody() !=null){
//            iEncoder.encode(nettyMessage.getBody(),sendBuf);
//        }else {
//            sendBuf.writeInt(0);
//        }
        //改写整个消息的长度，在第4个字节位置是该消息的长度
        sendBuf.setInt(4, sendBuf.readableBytes());
        //channelHandlerContext.writeAndFlush(sendBuf);
        list.add(sendBuf);
    }
}
